package cn.zifangsky.config;

import cn.zifangsky.model.ResponseVO;
import de.schlichtherle.license.LicenseContentException;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpStatus;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 全局异常处理
 *
 * @Author guoyb
 * @Date 2023/10/24  10:42
 */
@RestControllerAdvice
@Slf4j
public class WebExceptionHandler {


    //处理Get请求中 使用@Valid 验证路径中请求实体校验失败后抛出的异常，详情继续往下看代码
    @ExceptionHandler(BindException.class)
    public ResponseVO BindExceptionHandler(BindException e) {
        String message = e.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining());
        return ResponseVO.valiFail(message);
    }

    //处理请求参数格式错误 @RequestParam上validate失败后抛出的异常是javax.validation.ConstraintViolationException
    @ExceptionHandler(ConstraintViolationException.class)
    public ResponseVO ConstraintViolationExceptionHandler(ConstraintViolationException e) {
        String message = e.getConstraintViolations().stream().map(ConstraintViolation::getMessage).collect(Collectors.joining());
        return ResponseVO.valiFail(message);
    }

    //处理请求参数格式错误 @RequestBody上validate失败后抛出的异常是MethodArgumentNotValidException异常。
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseVO MethodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
        // String message = e.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining());

        BindingResult result = e.getBindingResult();
        List<FieldError> fieldErrors = result.getFieldErrors();
        String message = fieldErrors
                .stream()
                .map(fieldError -> {
                    return fieldError.getField().concat(":").concat(fieldError.getDefaultMessage());
                }) .collect(Collectors.joining("；"));
        return ResponseVO.valiFail(message);
    }

    @ExceptionHandler(Exception.class)
    public ResponseVO<String> ExceptionHandler(Exception e) {
        log.error("异常信息:{}",e.getMessage());
        e.printStackTrace();
        return new ResponseVO<>(null, HttpStatus.SC_INTERNAL_SERVER_ERROR, "系统异常");
    }



    @ExceptionHandler(LicenseContentException.class)
    public ResponseVO<String> LicenseContentExceptionHandler(LicenseContentException e) {
        log.error("License异常信息:{}",e.getMessage());
        return new ResponseVO<>(null, HttpStatus.SC_BAD_REQUEST, e.getMessage());
    }
}